#include "CPrimCSG.h"
#include "CNodeCSG.h"

//constructor destructor
CPrimCSG::CPrimCSG():m_root(0){}

CPrimCSG::CPrimCSG(CNodeCSG* root):m_root(root){}

CPrimCSG::~CPrimCSG()
{
	if(m_root != 0)
		delete m_root;
}

	//check intersection between a ray and the primitive
bool CPrimCSG::intersect(const CRay& ray, float& dist, bool useGlobalCoordinates)
{
	//change the coordinate system
	CRay r;
	if (useGlobalCoordinates)
		globalToLocal(ray, r);
	else
		convertRayToLocalCoordinates(ray, r);

	return m_root->checkIntersection(r, dist, m_normalTemp);
}

	//check inside
bool CPrimCSG::isInside(const CVector3f& p)
{
	//convert p to local coordinates
	CVector3f localP;
	convertPointToLocalCoordinates(p, localP);

	//test
	return m_root->isInside(localP);
}

	//gives the normal in a point
void CPrimCSG::computeNormal(const CRay& ray, float /*dist*/, CVector3f& normal)const
{
	//set the normal
	normal = m_normalTemp;

	//change the coordinate system
	CRay r;
	convertRayToLocalCoordinates(ray, r);

	//if ray from the inside
	if(r.getDirection().dot(normal) > 0)
		normal = normal * -1;

	//apply the wm to the normal
	convertNormalToGlobalCoordinates(normal, normal);
	
}

void CPrimCSG::applyViewMatrix(const CMatrix& view)
{
	//get the rotation part of the view matrix
	//CMatrix rotationView = view;
	//rotationView.m_array[3][0] = rotationView.m_array[3][1] = rotationView.m_array[3][2] = 0;

	//set the rotation view matrix
	//m_rotationViewMatrix = m_rotationMatrix * rotationView;

	//set the world view matrix
	m_worldViewMatrix = m_worldMatrix * view;

	//calculate the inverse
	//m_inverseRotationViewMatrix = m_rotationViewMatrix.inverse();
	m_inverseWorldViewMatrix = m_worldViewMatrix.inverse();

	//apply a null view matrix to the tree
	m_root->applyNullViewMatrix();

}